package com.px.business.service.impl;

import com.px.business.domain.EvaluationApplication;
import com.px.business.domain.EvaluationItem;
import com.px.business.domain.EvaluationItemRange;
import com.px.business.domain.EvaluationSystem;
import com.px.business.domain.dto.IndicatorRangeDTO;
import com.px.business.domain.dto.ItemRangeDTO;
import com.px.business.domain.dto.SystemIndicatorRangeDTO;
import com.px.business.domain.input.ItemInput;
import com.px.business.mapper.*;
import com.px.business.service.IEvaluationItemService;
import com.px.common.utils.StringUtils;
import com.px.common.utils.bean.BeanMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 评估明细项Service业务层处理
 *
 * @author 品讯科技
 * @date 2024-08
 */
@Service
public class EvaluationItemServiceImpl implements IEvaluationItemService {
    @Autowired
    private EvaluationItemMapper evaluationItemMapper;

    @Autowired
    private EvaluationItemRangeMapper evaluationItemRangeMapper;

    @Autowired
    private EvaluationIndicatorMapper evaluationIndicatorMapper;

    @Autowired
    private EvaluationApplicationMapper evaluationApplicationMapper;

    @Autowired
    private EvaluationSystemIndicatorMapper evaluationSystemIndicatorMapper;

    @Autowired
    private EvaluationSystemMapper evaluationSystemMapper;

    /**
     * 查询评估明细项
     *
     * @param evaluationItemId 评估明细项主键
     * @return 评估明细项
     */
    @Override
    public EvaluationItem selectEvaluationItemByEvaluationItemId(Long evaluationItemId) {
        return evaluationItemMapper.selectEvaluationItemByEvaluationItemId(evaluationItemId);
    }

    /**
     * 查询评估明细项列表
     *
     * @param evaluationItem 评估明细项
     * @return 评估明细项
     */
    @Override
    public List<EvaluationItem> selectEvaluationItemList(EvaluationItem evaluationItem) {
        return evaluationItemMapper.selectEvaluationItemList(evaluationItem);
    }

    /**
     * 新增评估明细项
     *
     * @param evaluationItem 评估明细项
     * @return 结果
     */
    @Override
    public int insertEvaluationItem(EvaluationItem evaluationItem) {
        return evaluationItemMapper.insertEvaluationItem(evaluationItem);
    }

    /**
     * 修改评估明细项
     *
     * @param evaluationItem 评估明细项
     * @return 结果
     */
    @Override
    public int updateEvaluationItem(EvaluationItem evaluationItem) {
        return evaluationItemMapper.updateEvaluationItem(evaluationItem);
    }

    /**
     * 批量删除评估明细项
     *
     * @param evaluationItemIds 需要删除的评估明细项主键
     * @return 结果
     */
    @Override
    public int deleteEvaluationItemByEvaluationItemIds(Long[] evaluationItemIds) {
        return evaluationItemMapper.deleteEvaluationItemByEvaluationItemIds(evaluationItemIds);
    }

    /**
     * 删除评估明细项信息
     *
     * @param evaluationItemId 评估明细项主键
     * @return 结果
     */
    @Override
    public int deleteEvaluationItemByEvaluationItemId(Long evaluationItemId) {
        return evaluationItemMapper.deleteEvaluationItemByEvaluationItemId(evaluationItemId);
    }

    @Override
    public boolean saveItemByIndicator(ItemInput itemInput) {
        // 1.根据申请标识、选中指标获取评估指标
        List<EvaluationItem> evaluationItemList = evaluationItemMapper.getItemListByIndicatorIds(itemInput.getApplicationId(), itemInput.getIndicatorIds());
        // 2.获取申请中所有的评估指标
        List<EvaluationItem> evaluationItemAllList = evaluationItemMapper.selectEvaluationItemList(new EvaluationItem(itemInput.getApplicationId()));
        // 3.入参指标转List
        List<String> indicatorList = Arrays.asList(itemInput.getIndicatorIds());
        // 4.筛选入参指标中有申请中没有的指标
        //取评估指标List
        List<String> itemList = evaluationItemList.stream().map(bean -> String.valueOf(bean.getEvaluationIndicatorId())).collect(Collectors.toList());
        //比较
        List<String> insertIdList = indicatorList.stream().filter(item -> !itemList.contains(item)).collect(Collectors.toList());
        // 5.筛选申请指标中有入参中没有的指标
        //取评估指标List
        List<String> itemAllList = evaluationItemAllList.stream().map(bean -> String.valueOf(bean.getEvaluationIndicatorId())).collect(Collectors.toList());
        //比较
        List<String> deleteIdList = itemAllList.stream().filter(item -> !indicatorList.contains(item)).collect(Collectors.toList());
        // 6.新增
        if (insertIdList.size() > 0) {
            List<IndicatorRangeDTO> indicatorRangeDTOList = evaluationIndicatorMapper.getIndicatorRangeByIndicatorIds(insertIdList);
            indicatorRangeDTOList.forEach(bean -> {
                EvaluationItem evaluationItem = new EvaluationItem(itemInput.getApplicationId(), bean.getEvaluationIndicatorId(), bean.getEvaluationIndicatorType(), bean.getEvaluationIndicatorLevel(), bean.getEvaluationIndicatorDescription(), bean.getParentId(), bean.getDefaultWeights(), bean.getEvaluationDept(), bean.getAssistDept(), bean.getSeqNo());
                evaluationItemMapper.insertEvaluationItem(evaluationItem);
                if (bean.getEvaluationRangeList().size() > 0) {
                    evaluationItemRangeMapper.insertRangeBatch(evaluationItem.getEvaluationItemId(), bean.getEvaluationRangeList());
                }
            });
        }
        // 7.删除
        if (deleteIdList.size() > 0) {
            evaluationItemMapper.deleteItemByIndicatorIds(itemInput.getApplicationId(), deleteIdList);
        }
        return true;
    }

    @Override
    public boolean saveItemBySystem(ItemInput itemInput) {
        // 删除所有申请下的指标
        evaluationItemMapper.deleteItemByApplicationId(itemInput.getApplicationId());
        // 查询指标体系下所有的指标及范围
        List<SystemIndicatorRangeDTO> systemIndicatorRangeDTOList = evaluationSystemIndicatorMapper.getSystemIndicatorRangeBySystemId(itemInput.getEvaluationSystemId());
        systemIndicatorRangeDTOList.forEach(bean -> {
            EvaluationItem evaluationItem = new EvaluationItem(itemInput.getApplicationId(), bean.getEvaluationIndicatorId(), bean.getEvaluationIndicatorType(), bean.getEvaluationIndicatorLevel(), bean.getEvaluationIndicatorDescription(), bean.getParentId(), bean.getEvaluationWeight(), bean.getEvaluationDept(), bean.getAssistDept(), bean.getSeqNo());
            evaluationItemMapper.insertEvaluationItem(evaluationItem);
            if (bean.getEvaluationRangeList().size() > 0) {
                evaluationItemRangeMapper.insertRangeBatch(evaluationItem.getEvaluationItemId(), bean.getEvaluationRangeList());
            }
        });
        // 修改总分
        EvaluationSystem evaluationSystem = evaluationSystemMapper.selectEvaluationSystemByEvaluationSystemId(itemInput.getEvaluationSystemId());
        evaluationApplicationMapper.updateEvaluationApplication(new EvaluationApplication(itemInput.getApplicationId(), evaluationSystem.getTotalPoints()));
        return true;
    }

    @Override
    public List<Map> getItemRange(ItemInput itemInput) {
        List<ItemRangeDTO> itemRangeDTOList = evaluationItemMapper.getItemRangeByApplicationId(itemInput.getApplicationId());
        List<ItemRangeDTO> allItemRange = turnColumn(itemRangeDTOList);

        // 过滤出3级指标
        List<ItemRangeDTO> thirdItemRange = allItemRange.stream()
                .filter(bean -> "3".equals(bean.getEvaluationIndicatorLevel()))
                .sorted(Comparator.comparingLong(ItemRangeDTO::getParentId).thenComparing(ItemRangeDTO::getSeqNo))
                .collect(Collectors.toList());
        thirdItemRange.stream().peek(bean -> {
            // 根据父ID找到二级指标
            List<ItemRangeDTO> secondItemRangeOne = allItemRange.stream().filter(all -> all.getEvaluationIndicatorId().equals(bean.getParentId())).collect(Collectors.toList());
            ItemRangeDTO secondItemRange = secondItemRangeOne.get(0);
            bean.setSecondItem(secondItemRange);
            // 根据父ID找到一级指标
            List<ItemRangeDTO> firstItemRangeOne = allItemRange.stream().filter(all -> all.getEvaluationIndicatorId().equals(secondItemRange.getParentId())).collect(Collectors.toList());
            ItemRangeDTO firstItemRange = firstItemRangeOne.get(0);

            // 反找到所有二级指标
            //List<ItemRangeDTO> secondItemRangeList = allItemRange.stream()
            //        .filter(all -> all.getParentId().equals(firstItemRange.getEvaluationIndicatorId())).collect(Collectors.toList());
            // 反找到所有三级指标，合计权重
            //List<ItemRangeDTO> thirdItemRangeList = allItemRange.stream()
            //        .filter(all -> secondItemRangeList.stream()
            //                .anyMatch(second -> all.getParentId().equals(second.getEvaluationIndicatorId())))
            //        .collect(Collectors.toList());
            //Long secondSum = thirdItemRangeList.stream().filter(range -> StringUtils.isNotNull(range.getEvaluationWeight())).mapToLong(ItemRangeDTO::getEvaluationWeight).sum();
            //firstItemRange.setEvaluationWeight(secondSum);
            bean.setFirstItem(firstItemRange);
        }).collect(Collectors.toList());

        List<Map> itemRangeMap;
        // 增加专家评分
        if (itemInput.getExpertBy() == null) {
            itemRangeMap = BeanMapper.mapList(thirdItemRange, ItemRangeDTO.class, Map.class);
        } else {
            if (itemInput.getExpertBy() == 0) {
                itemRangeMap = thirdItemRange.stream().map(bean -> {
                    Map map = BeanMapper.map(bean, Map.class);
                    bean.getExpertScoreDTOList()
                            //.filter(f -> f.getExpertBy().equals(evaluationInput.getExpertBy()) || 0 == evaluationInput.getExpertBy())
                            .forEach(score -> map.put(String.valueOf(score.getExpertBy()), score.getExpertScore()));
                    return map;
                }).collect(Collectors.toList());
            } else {
                //thirdItemRange = thirdItemRange.stream().peek(bean -> {
                //    List<ExpertScoreDTO> expertScoreDTOList = bean.getExpertScoreDTOList().stream().filter(f -> f.getExpertBy().equals(evaluationInput.getExpertBy())).collect(Collectors.toList());
                //    bean.setEvaluationScoreId(expertScoreDTOList.get(0).getEvaluationScoreId());
                //    bean.setExpertScore(expertScoreDTOList.get(0).getExpertScore());
                //}).collect(Collectors.toList());
                itemRangeMap = thirdItemRange.stream().map(bean -> {
                    Map map = BeanMapper.map(bean, Map.class);
                    bean.getExpertScoreDTOList().stream()
                            .filter(f -> f.getExpertBy().equals(itemInput.getExpertBy()))
                            .forEach(score -> {
                                map.put("evaluationExpertId", score.getEvaluationExpertId());
                                map.put("evaluationScoreId", score.getEvaluationScoreId());
                                map.put("expertLevel", score.getExpertLevel());
                                map.put("expertScore", score.getExpertScore());
                            });
                    return map;
                }).collect(Collectors.toList());
            }
        }
        return itemRangeMap;
    }

    @Override
    public Map<String, String> checkItemRange(ItemInput itemInput) {
        Map<String, String> map = new HashMap<>();
        map.put("code", "0");
        map.put("msg", "校验通过");
        Long num = 100L;
        List<ItemRangeDTO> itemRangeDTOList = evaluationItemMapper.getItemRangeByApplicationId(itemInput.getApplicationId());
        List<ItemRangeDTO> allItemRange = turnColumn(itemRangeDTOList);
        EvaluationApplication evaluationApplication = evaluationApplicationMapper.selectEvaluationApplicationByEvaluationApplicationId(itemInput.getApplicationId());
        // 过滤出所有的一级指标
        List<ItemRangeDTO> firstItemRangeList = allItemRange.stream()
                .filter(bean -> "1".equals(bean.getEvaluationIndicatorLevel()))
                .sorted(Comparator.comparing(ItemRangeDTO::getSeqNo))
                .collect(Collectors.toList());
        //计算所有一级指标的分数值是否跟申请上的总分一致
        Long firstSum = firstItemRangeList.stream().filter(range -> StringUtils.isNotNull(range.getEvaluationWeight())).mapToLong(ItemRangeDTO::getEvaluationWeight).sum();
        if (!evaluationApplication.getTotalPoints().equals(firstSum)) {
            map.put("code", "1");
            map.put("msg", "一级指标总分不足" + evaluationApplication.getTotalPoints());
            return map;
        }
        //计算一级指标下的二级指标总站比，并判断
        for (ItemRangeDTO itemRangeDTO : firstItemRangeList) {
            // 根据父ID找到二级指标
            List<ItemRangeDTO> secondItemRangeList = allItemRange.stream().filter(all -> all.getParentId().equals(itemRangeDTO.getEvaluationIndicatorId())).collect(Collectors.toList());
            //判断二级级指标总占比是否是100%
            Long secondSum = secondItemRangeList.stream().filter(range -> StringUtils.isNotNull(range.getEvaluationWeight())).mapToLong(ItemRangeDTO::getEvaluationWeight).sum();
            if (!num.equals(secondSum)) {
                map.put("code", "2");
                map.put("msg", "一级指标'" + itemRangeDTO.getEvaluationIndicatorDescription() + "'下的二级指标总占不足100%");
                return map;
            }
        }
        // 过滤出所有的二级指标
        List<ItemRangeDTO> secondItemRangeList = allItemRange.stream()
                .filter(bean -> "2".equals(bean.getEvaluationIndicatorLevel()))
                .sorted(Comparator.comparing(ItemRangeDTO::getSeqNo))
                .collect(Collectors.toList());

        //计算二级级指标下的一级指标总权重，并判断
        for (ItemRangeDTO itemRangeDTO : secondItemRangeList) {
            // 根据父ID找到二级指标
            List<ItemRangeDTO> thirdItemRangeList = allItemRange.stream().filter(all -> all.getParentId().equals(itemRangeDTO.getEvaluationIndicatorId())).collect(Collectors.toList());
            //判断三级指标中权重是否是100%
            Long secondSum = thirdItemRangeList.stream().filter(range -> StringUtils.isNotNull(range.getEvaluationWeight())).mapToLong(ItemRangeDTO::getEvaluationWeight).sum();
            if (!num.equals(secondSum)) {
                map.put("code", "3");
                map.put("msg", "二级指标'" + itemRangeDTO.getEvaluationIndicatorDescription() + "'下的三级级指标总权重不足100%");
                return map;
            }
        }
        return map;
    }

    /**
     * 行转列
     *
     * @param itemRangeDTOList 值域
     * @return 结果
     */
    private List<ItemRangeDTO> turnColumn(List<ItemRangeDTO> itemRangeDTOList) {
        itemRangeDTOList = itemRangeDTOList.stream().peek(bean -> {
            String observation = bean.getEvaluationItemRangeList().stream()
                    .sorted(Comparator.comparing(EvaluationItemRange::getLevelValue, Comparator.nullsLast(String::compareTo)))
                    .map(range -> range.getLevelValue() + "(" + range.getEvaluationProportion() + "%)：" + range.getEvaluationValue())
                    .collect(Collectors.joining("|"));
            bean.setObservation(observation);
        }).collect(Collectors.toList());
        return itemRangeDTOList;
    }

    @Override
    public List<Long> selectEvaluationItemByEvaluationApplicationId(Long evaluationApplicationId) {
        return evaluationItemMapper.selectEvaluationItem(evaluationApplicationId);
    }

    @Override
    public int updateEvaluationItemFile(EvaluationItem evaluationItem) {
        return evaluationItemMapper.updateEvaluationItemFile(evaluationItem);
    }


}
